// Package controller 用户控制器包
// @title 网址速藏系统 API
// @version 1.0
// @description 一个基于Go语言开发的网址收藏系统
// @termsOfService http://example.com/terms/
// @contact.name API Support
// @contact.url http://www.example.com/support
// @contact.email support@example.com
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:9080
// @BasePath /api
// @schemes http https
package controller

import (
	"bookmark-web/logic"
	"bookmark-web/middleware"
	"bookmark-web/models"
	"bookmark-web/utils"
	"fmt"
	"log"

	"github.com/gin-gonic/gin"
)

// 路由设置
func SetupUserRouter(r *gin.RouterGroup) {
	// 不需要认证的用户路由
	r.POST("/user/register", Register) // 用户注册
	r.POST("/user/login", Login)       // 用户登录

	// 需要认证的用户路由
	user := r.Group("/user")
	user.Use(middleware.JWTAuthMiddleware())
	{
		user.GET("/list", GetUserList)   // 获取用户列表
		user.GET("/:id", GetUserById)    // 获取用户详情
		user.PUT("/:id", UpdateUserById) // 修改用户信息
	}
}

// Register 用户注册控制器
// @Summary 用户注册
// @Description 用户注册接口，创建新用户
// @Tags 用户相关
// @Accept json
// @Produce json
// @Param data body models.UserRegisterRequest true "注册信息"
// @Success 200 {object} utils.Response "注册成功"
// @Router /user/register [post]
func Register(c *gin.Context) {
	log.Printf("收到注册请求: %s %s", c.Request.Method, c.Request.URL.Path)

	// 1. 绑定请求参数
	var req models.UserRegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 短变量声明与条件检查合并
		// ShouldBindJSON 方法会： 解析请求中的 JSON 数据，将解析后的数据绑定到 req 结构体中，如果解析或绑定过程中出现错误，返回相应的错误信息

		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	log.Printf("注册用户名: %s, 邮箱: %s", req.Username, req.Email)

	// 2. 调用业务逻辑层处理注册
	userResp, err := logic.RegisterUser(&req)
	if err != nil {
		log.Printf("用户注册失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 3. 返回成功响应
	utils.Success(c, "注册成功", userResp)
}

// Login 用户登录控制器
// @Summary 用户登录
// @Description 用户登录接口，获取JWT令牌
// @Tags 用户相关
// @Accept json
// @Produce json
// @Param data body models.UserLoginRequest true "登录信息"
// @Success 200 {object} map[string]interface{} "登录成功，返回令牌和用户信息"
// @Router /user/login [post]
func Login(c *gin.Context) {
	log.Printf("收到登录请求: %s %s", c.Request.Method, c.Request.URL.Path)

	// 1. 绑定请求参数
	var req models.UserLoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	log.Printf("登录用户名: %s", req.Username)

	// 2. 调用业务逻辑层处理登录
	userResp, err := logic.LoginUser(&req)
	if err != nil {
		log.Printf("用户登录失败: %v", err)
		utils.Error(c, err.Error())
		return
	}

	// 3. 生成JWT令牌
	token, err := utils.GenerateToken(userResp.ID, userResp.Username)
	if err != nil {
		log.Printf("生成JWT令牌失败: %v", err)
		utils.Error(c, "登录失败，请重试")
		return
	}

	// 4. 设置Cookie（可选）
	c.SetCookie("token", token, 3600*24*7, "/", "", false, true) // 7天有效期

	// 5. 返回成功响应，包含令牌
	utils.Success(c, "登录成功", gin.H{
		"user":  userResp,
		"token": token,
	})
}

// GetUserList 获取用户列表
// @Summary 获取用户列表
// @Description 获取所有用户信息列表
// @Tags 用户相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} utils.Response "获取成功"
// @Router /user/list [get]
func GetUserList(c *gin.Context) {
	// 调用业务逻辑层获取所有用户
	users, err := logic.GetAllUsers()
	if err != nil {
		log.Printf("获取用户列表失败: %v", err)
		utils.Error(c, "获取用户列表失败")
		return
	}

	utils.Success(c, "获取成功", users)
}

// GetUserById 获取用户详情信息
// @Summary 获取用户详情
// @Description 根据ID获取用户详细信息
// @Tags 用户相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "用户ID"
// @Success 200 {object} utils.Response "获取成功"
// @Router /user/{id} [get]
func GetUserById(c *gin.Context) {
	// 1. 获取用户ID
	id := c.Param("id")
	// 2. 调用业务逻辑层获取用户详情
	user, err := logic.GetUserInfo(id)
	if err != nil {
		log.Printf("获取用户详情失败: %v", err)
		utils.Error(c, "获取用户详情失败")
		return
	}
	// 3. 返回成功响应
	utils.Success(c, "获取成功", user)
}

// UpdateUserById 修改用户信息
// @Summary 修改用户信息
// @Description 根据ID修改用户信息
// @Tags 用户相关
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path string true "用户ID"
// @Param data body map[string]interface{} true "更新信息"
// @Success 200 {object} utils.Response "修改成功"
// @Router /user/{id} [put]
func UpdateUserById(c *gin.Context) {
	// 1. 获取用户ID
	idStr := c.Param("id")
	userID := getUserID(c) // 从JWT中获取当前用户ID

	// 2. 验证用户只能修改自己的信息
	if idStr != fmt.Sprintf("%d", userID) {
		utils.Error(c, "无权限修改其他用户信息")
		return
	}

	// 3. 绑定请求参数
	var req models.UserUpdateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		log.Printf("参数绑定失败: %v", err)
		utils.InvalidParams(c, "请求参数格式错误")
		return
	}

	log.Printf("用户更新请求 - 用户ID: %d, 请求数据: %+v", userID, req)

	// 4. 调用业务逻辑层修改用户信息
	userResp, err := logic.UpdateUserById(userID, &req)
	if err != nil {
		log.Printf("修改用户信息失败: %v", err)
		utils.Error(c, err.Error())
		return
	}
	utils.Success(c, "修改成功", userResp)
}

// Index 首页
func Index(c *gin.Context) {
	c.HTML(200, "index.html", gin.H{
		"title": "网址收藏系统",
	})
}

// RegisterPage 注册页面
func RegisterPage(c *gin.Context) {
	c.HTML(200, "register.html", gin.H{
		"title": "用户注册",
	})
}

// LoginPage 登录页面
func LoginPage(c *gin.Context) {
	c.HTML(200, "login.html", gin.H{
		"title": "用户登录",
	})
}
